<template>
  <Scroll
  @scroll="scroll"
  :listen-scroll="true"
  ref="listview"
  :probe-type="probeType"
  class="listview">
  <ul>
    <li  v-for="group in datalist" class="list-group" ref="listGroup">
      <h2 v-if='group.title' class="list-group-title" v-html="group.title"></h2>
      <ul>
      <!-- 业务逻辑相关的事件全部emit到核心组件处理 -->
        <li v-for="item in group.items" @click='selectItem(item)' class="list-group-item">
          <img class="avatar" v-lazy="item.avatar" alt="歌手头像">
          <span class="name" v-html='item.name'></span>
        </li>
      </ul>
    </li>
  </ul>
  <div class="list-shortcut"
  @touchstart.stop.prevent="onShortcutTouchStart"
  @touchmove.stop.prevent="onShortcutTouchMove"
  @touchend.stop>
    <ul>
      <li v-for="(item, index) in datalist" class='item' :class="{current:index == currentIndex}" v-html="item.title.substring(0,1)" v-if='item.title'  :data-index='index'>
      </li>
    </ul>
  </div>
  <div class="list-fixed" ref="fixed" v-show='scrollY<=0'>
    <div class="fixed-title" v-html='fixedTitle'></div>
  </div>
  <div  class="loading-container" v-if="!datalist.length">
    <loading ></loading>
  </div>
</Scroll>
</template>
<script>
  import loading from '@/base/loading';
  import Scroll from '@/base/scroll';
  import { needAttr } from '@/common/js/dom';

  const ANCHOR_HEIGHT = 18;
  const TITLE_HEIGHT = 30;

  export default {
    name: 'list-view',
    props: {
      datalist: {
        default: [],
        type: Array,
      },
    },
    computed: {
      fixedTitle() {
        if (this.datalist.length > 0) {
          const item = this.datalist[this.currentIndex];
          return item.title || '';
        }
        return '';
      },
    },
    methods: {
      selectItem(item) {
        this.$emit('select', item);
      },
      onShortcutTouchStart(eve) {
        const firstTouch = eve.touches[0];
        if (firstTouch.target.nodeName !== 'LI') {
          return;
        }
        // 记录起始index及scrollY
        this.touchAnchor.start = needAttr(eve.touches[0].target, 'index') - 0;
        this.currentIndex = this.touchAnchor.start;
        this.touchAnchor.y1 = firstTouch.pageY;
        this._scrollTo(this.currentIndex);
      },
      onShortcutTouchMove(eve) {
        const firstTouch = eve.touches[0];
        if (firstTouch.target.nodeName !== 'LI') {
          return;
        }
        // 记录终点scrollY
        this.touchAnchor.y2 = firstTouch.pageY;
        // 通过高度差/每个li的height 计算出偏移index
        this.delIndex = Math.floor((this.touchAnchor.y2 - this.touchAnchor.y1) / ANCHOR_HEIGHT);
        // 起点 + delIndex 得到最后的index
        this.touchAnchor.final = this.touchAnchor.start + this.delIndex;
        // 边界情况
        this.currentIndex = this.touchAnchor.final;
        if (this.touchAnchor.final < 0) {
          // 超出头部
          this.currentIndex = 0;
        } else if (this.touchAnchor.final >= this.datalist.length) {
          this.currentIndex = this.datalist.length - 1;
        }
        this._scrollTo(this.currentIndex);
      },
      refresh() {
        this.$refs.listview.refresh();
      },
      scroll(pos) {
        // contentUl 滚动过程中
        const listHeight = this.listHeight;
        this.scrollY = pos.y;
        // scroll超出头部
        if (pos.y > 0) {
          this.currentIndex = 0;
          return;
        }
        // 在内容区,遍历listHeight判断当前所处index 这里是length-1
        for (let i = 0; i < listHeight.length - 1; i++) {
          const height1 = listHeight[i];
          const height2 = listHeight[i + 1];
          if (-pos.y >= height1 && -pos.y < height2) {
            this.currentIndex = i;
            // todo 关键性的一步,判断fixedTitle需要变化的条件
            this.diff = height2 + pos.y;
            // 这里diff的变化放在watch里单独处理
            return;
          }
        }
        // 当最后一个height2也判断不通过,那么很明显scroll已经超出底部了
        this.currentIndex = listHeight.length - 1;
      },
      _scrollTo(index) {
        this.$refs.listview.scrollToElement(this.$refs.listGroup[index], 0);
      },
      _calculateHeight() {
        const list = this.$refs.listGroup;
        let height = 0;
        this.listHeight.push(height);
        for (let i = 0; i < list.length; i++) {
          const item = list[i];
          height += item.clientHeight;
          this.listHeight.push(height);
        }
      },
    },
    data() {
      return {
        probeType: 3,
        currentIndex: 0,
        touchAnchor: {},
        delH: 0,
        listHeight: [],
        scrollY: 0,
        diff: -1,
      };
    },
    watch: {
      diff(newVal) {
        // fixedTitle 滚动完一个TITLE_HEIGHT之后就可以回到0了
        const fixedTop = (newVal > 0 && newVal < TITLE_HEIGHT) ? newVal - TITLE_HEIGHT : 0;
        if (fixedTop === this.fixedTop) {
          return;
        }
        this.fixedTop = fixedTop;
        // todo 开启3D渲染
        this.$refs.fixed.style.transform = `translate3d(0,${fixedTop}px,0)`;
      },
    },
    mounted() {
      this._calculateHeight();
    },
    components: {
      Scroll,
      loading,
    },
  };
</script>
<style lang='stylus' scoped>
@import '~styl/var'
.list-group
  .list-group-title
    height 30px
    line-height 30px
    padding-left 20px
    font-size $font-size-small
    color $color-text-l
    background $color-highlight-background
  ul
    background #222
    .list-group-item
      display flex
      padding 20px 0 0 30px
      align-items center
      &:last-child
        padding-bottom 20px
      .avatar
        width 50px
        height 50px
        border-radius 50%
      .name
        margin-left 20px
        color $color-text-l
        font-size $font-size-medium
.list-shortcut
  position: absolute
  z-index: $higher
  right: 0
  top: 50%
  transform: translateY(-50%)
  width: 20px
  padding: 20px 0
  border-radius: 10px
  text-align: center
  background: $color-background-d
  font-family: Helvetica
  .item
    padding: 3px
    color: $color-text-l
    font-size: $font-size-small
    &.current
      color: $color-theme
.list-fixed
  position absolute
  top 0
  left 0
  width 100%
  .fixed-title
    height 30px
    line-height 30px
    padding-left 20px
    font-size $font-size-small
    color $color-text-l
    background $color-highlight-background
</style>
